const {ccclass, property} = cc._decorator;

/*
gameMap脚本:附加在Map节点上，存储所有的怪物行走路径和建塔区域
Monster脚本：附加在怪物节点上，控制怪物行走和碰撞逻辑
MonsterSpwan脚本：附加在start01上，控制怪物的孵化
MonsterManger脚本:怪物管咯
TowerSpwan脚本:附加在Map节点上，点击建塔
TowerTool脚本:建塔工具脚本
Tower脚本：控制塔的转向和发射子弹
Bullet脚本：控制子弹的朝向和移动
BulletManager:子弹管理类

作业：1.读取Obj相关的对象，存储towerArea
      2.添加一个怪物管理类(单例模式,添加数组管理怪物)
*/

@ccclass
export default class GameMap extends cc.Component {

    @property(cc.SpriteAtlas)
    uiSpriteAtlas:cc.SpriteAtlas = null
    
    // 定义存储cc.Vec2(路径点)的数组
    @property([cc.Vec2])
    wayPoints:cc.Vec2[] = [];

    //定义存储cc.Rect(建塔区域)的数组
    towerArea:cc.Rect[] = [];

    //存放下标
    objectIndex:number[] = [];

    objectGroup:cc.TiledObjectGroup = null

    private objectMap = new Map<string, any>()

    onLoad(){
        //碰撞的必要条件：要求两者都需要有碰撞器(Collider)组件
        // 1.通过导演获得碰撞管理器
        let manager = cc.director.getCollisionManager()

        // 2.开启碰撞器管理
        manager.enabled = true
        
        // 3.开启碰撞盒绘制
        manager.enabledDrawBoundingBox = true

        // 4.是否开启碰撞盒形状的绘制
        manager.enabledDebugDraw = true
    }

    start () {
        //读取瓦片地图的对象层得到路径 PT
        // 1.得到TiledObjectGroup组件
        this.objectGroup = this.getComponentInChildren(cc.TiledMap).getObjectGroup("PATH")
        // 2.得到所有的对象
        const objects = this.objectGroup.getObjects()
        // 3.将所有对象转换为键值对形式(名字对应对象)  Map<键类型，值类型>
        
        //set(键，值)   添加键值对
        //get(键)       通过键获取值
        for(const obj of objects){
            this.objectMap.set(obj.name,obj)
        }
        this.loadEnemyRoute()
        this.loadObstacleObject()
        this.loadTowerArea()
    }

    update (dt) {
        
    }

    //通过共同部分的名字查找同意类型的对象,返回数组
    getMapObjects(name:string) : any[]{
        let objects:any[] = []
        if(name == "Ob"){
            for(let i = 1; i <= 7; i++){
                for(let j = 1; j <= 5; j++){
                    let obj = this.objectMap.get(`${i}Ob${j}`)
                    if(obj != null){
                        objects.push(obj)               
                        this.objectIndex.push(i)
                    }
                }
            }
        }else{
            let index = 1
            while(true){
                if(this.objectMap.get(name + index) != null){
                    objects.push(this.objectMap.get(name + index++))
                }else{
                    break
                }
            }
        }

        return objects
    }

    //加载怪物行走路径
    loadEnemyRoute(){
        const ptArr = this.getMapObjects("PT")
        for(let i = 0; i < ptArr.length; i++){
            const pos = this.tiledMapToCanvas(new cc.Vec2(ptArr[i].x, ptArr[i].y))
            this.wayPoints.push(new cc.Vec2(pos.x + 40, pos.y))
        }
    }

    //加载地图中的物体
    loadObstacleObject(){
        let objectArea = this.getMapObjects("Ob")
        for(let i = 0; i < this.objectIndex.length; i++){
            //创建物体节点
            let obj:cc.Node = new cc.Node()
            obj.addComponent(cc.Sprite)
            obj.getComponent(cc.Sprite).spriteFrame = this.uiSpriteAtlas.getSpriteFrame(`cloud0${this.objectIndex[i]}`)
            obj.setAnchorPoint(0,1)
            const pos = this.tiledMapToCanvas(new cc.Vec2(objectArea[i].x, objectArea[i].y))
            obj.setPosition(pos)
            obj.active = true
            this.node.addChild(obj);
        }
    }

    //加载建塔区域数组
    loadTowerArea(){
        const objArr = this.getMapObjects("Obj")
        objArr.forEach((obj,index) => {
            // let pos = this.tiledMapToCanvas(new cc.Vec2(obj.x, obj.y))
            let rect = new cc.Rect()
            rect.x = obj.x
            rect.y = obj.y - obj.height
            rect.width = obj.width
            rect.height = obj.height //瓦片地图矩形以左上角为原点
            this.splitRect(rect).forEach(item =>{
                this.towerArea.push(item)
            })
        });

        // this.schedule(this.showTowerArea,1,3,0.5)
        // this.showTowerArea()
    }

    //拆分矩形区域
    splitRect(rect:cc.Rect):cc.Rect[]{
        let rects:cc.Rect[] = []
        const splitXCount = rect.width / 80
        const splitYCount = rect.height / 80
        for(let j = 0; j < splitYCount; j++){
            for(let i = 0; i < splitXCount; i++){
                let tempRect = new cc.Rect()
                tempRect.x = rect.x + (i * 80)
                tempRect.y = rect.y + (j * 80)
                tempRect.width = 80
                tempRect.height = 80
                rects.push(tempRect)
            }
        }
        return rects
    }

    //显示所有建塔区域
    showTowerArea(){
        this.towerArea.forEach((item,index) =>{
            cc.loader.loadRes("prefabs/towerAredSelect.prefab", (err, prefab) => {
                //实例化
                let towerNode = cc.instantiate(prefab);
                let pos = this.getComponent(GameMap).tiledMapToCanvas(new cc.Vec2(item.x, item.y))
                towerNode.setPosition(pos.x + 40, pos.y + 35);
                towerNode.setParent(cc.find("Canvas"))
            })
        })
    }

    //从瓦片地图转换到Canvas坐标系下
    tiledMapToCanvas(point:cc.Vec2):cc.Vec2{
        const x = point.x - cc.winSize.width / 2
        const y = point.y - cc.winSize.height / 2
        return new cc.Vec2(x, y)
    }
}
